package com.bootcamp.mall.controller.admin;

/**
 * @program: mall
 * @author: Keyu Li
 * @create: 2021-11-09 09:13
 **/

import com.bootcamp.mall.model.Result;
import com.bootcamp.mall.model.bo.admin.AddAdminBO;
import com.bootcamp.mall.model.bo.admin.AdminLoginInfoBO;
import com.bootcamp.mall.model.bo.admin.SearchAdminBO;
import com.bootcamp.mall.model.bo.admin.UpdateAdminBO;
import com.bootcamp.mall.model.bo.admin.ChangeAdminPwdBO;
import com.bootcamp.mall.model.vo.admin.AdminLoginInfoVO;
import com.bootcamp.mall.model.vo.admin.AllAdminInfoVO;
import com.bootcamp.mall.service.admin.AdminService;
import com.bootcamp.mall.service.admin.AdminServiceImpl;
import com.bootcamp.mall.utils.JSONUtil;
import com.bootcamp.mall.utils.StringUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet(name = "AdminServlet", value = "/api/admin/admin/*")
public class AdminServlet extends HttpServlet {
    // 每个thread有自己的sqlsession，统一用户不同请求属于同一thread
    AdminService adminService = new AdminServiceImpl();
    // gson可以公用
    Gson gson = new Gson();

    //TODO：设置超级管理员权限，普通管理员无法查看密码，无法进行update，delete，add管理员操作

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取具体servlet
        String op = request.getRequestURI().replace("/api/admin/admin/", "");
        if ("allAdmins".equals(op)) {
            opAllAdmins(request, response);
        } else if ("getAdminsInfo".equals(op)) {
            opGetAdminInfo(request, response);
        } else if ("deleteAdmins".equals(op)) {
            opDeleteAdmins(request, response);
        }
    }


    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String op = request.getRequestURI().replace("/api/admin/admin/", "");
        if ("login".equals(op)) {
            opLogin(request, response);
        } else if ("addAdminss".equals(op)) {
            opAddAdmins(request, response);
        } else if ("updateAdminss".equals(op)) {
            opUpdateAdmins(request, response);
        } else if ("getSearchAdmins".equals(op)) {
            opGetSearchAdmins(request, response);
        } else if ("changePwd".equals(op)) {
            opChangePwd(request, response);
        } else if ("logoutAdmin".equals(op)) {
            opLogoutAdmin(request, response);
        }
    }

    private void opLogoutAdmin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 清除当前 session
        request.getSession().invalidate();
        response.getWriter().println(gson.toJson(Result.ok()));
    }

    private void opChangePwd(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        //将json字符串转化为 bo
        String jsonContent = JSONUtil.parseContent(request);
        // 感觉不需要校验就可以了……
        if (StringUtil.isEmpty(jsonContent)) {
            // 字符串为空，前端错误
            writer.println(gson.toJson(new Result(8000, "前端异常！", null)));
            return;
        }
        // 封装为bo对象
        JsonObject asJsonObject = new JsonParser().parse(jsonContent).getAsJsonObject();
        ChangeAdminPwdBO adminBO = gson.fromJson(asJsonObject, ChangeAdminPwdBO.class);
        // service校验及查询
        Integer code = adminService.changePwd(adminBO);
        if (code == 400) {
            // 密码不一致
            writer.println(gson.toJson(new Result(400, "两次输入密码不一致！", null)));
            return;
        } else if (code == 401) {
            // 新密码为空
            writer.println(gson.toJson(new Result(401, "新密码不能为空！", null)));
            return;
        } else if (code == 402) {
            // 修改admin密码
            writer.println(gson.toJson(new Result(401, "禁止修改admin密码！", null)));
            return;
        } else if (code == 0) {
            // 原密码错误
            writer.println(gson.toJson(new Result(402, "原密码错误！", null)));
            return;
        } else if (code == 1) {
            // 修改密码成功
            writer.println(gson.toJson(new Result(0, null, null)));
            return;
        }
        writer.println(gson.toJson(new Result(500, "未知错误！", null)));
    }

    /**
     * 通过email 或 nickname 模糊搜索
     *
     * @param request:
     * @param response:
     * @return void
     * @date 11/9/2021 16:48
     */
    private void opGetSearchAdmins(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        // 解析json字符串为json
        String jsonContent = JSONUtil.parseContent(request);
        if (StringUtil.isEmpty(jsonContent)) {
            // 字符串为空，前端错误
            writer.println(gson.toJson(new Result(8000, "前端异常！", null)));
            return;
        }
        // 封装为bo对象
        JsonObject asJsonObject = new JsonParser().parse(jsonContent).getAsJsonObject();
        SearchAdminBO adminBO = gson.fromJson(asJsonObject, SearchAdminBO.class);
        // service查询，返回vo list
        List<AllAdminInfoVO> adminVOs = adminService.getSearchAdmins(adminBO);
        response.getWriter().println(gson.toJson(new Result(0, null, adminVOs)));
    }

    private void opDeleteAdmins(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        // getParamter获得id
        int id;
        try {
            id = Integer.parseInt(request.getParameter("id"));
        }catch (NumberFormatException e){
            writer.println(gson.toJson(Result.error("前端参数异常！")));
            return;
        }
        // 删除id对应的admin
        Integer code = adminService.deleteAdmins(id);
        if (code == -1) {
            //删除的是admin用户
            writer.println(gson.toJson(new Result(1000, "不能删除admin用户！", null)));
            return;
        } else if (code == 1) {
            //正常删除
            writer.println(gson.toJson(new Result(0, null, null)));
            return;
        }
        // 前端/后端发生错误
        writer.println(gson.toJson(new Result(500, "未知错误", null)));

    }

    private void opUpdateAdmins(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 数据库添加相同username会抛出异常，而不是返回 0
        PrintWriter writer = response.getWriter();
        // 解析json字符串，封装为 updateAdminBO对象
        String jsonContent = JSONUtil.parseContent(request);
        // 如果浏览器传来空字符串
        if (StringUtil.isEmpty(jsonContent)) {
            writer.println(gson.toJson(new Result(8000, "前端返回错误！", null)));
            return;
        }
        // 解析为bo对象
        JsonObject asJsonObject = new JsonParser().parse(jsonContent).getAsJsonObject();
        UpdateAdminBO adminBO = gson.fromJson(asJsonObject, UpdateAdminBO.class);
        // 得到code
        int code = adminService.updateAdminss(adminBO);
        if (code == 0) {
            writer.println(gson.toJson(new Result(10000, "修改失败！不能有相同用户名", null)));
            return;
        } else if (code == 1) {
            // 更新信息成功
            writer.println(gson.toJson(new Result(0, null, null)));
            return;
        }
        writer.println(gson.toJson(new Result(500, "服务器内部错误！", null)));
    }


    private void opGetAdminInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        int id;
        try {
            id = Integer.parseInt(request.getParameter("id"));
        }catch (NumberFormatException e){
            writer.println(gson.toJson(Result.error("前端参数异常！")));
            return;
        }

        // service
        AllAdminInfoVO adminVO = adminService.getAdminsInfo(id);
        if (adminVO == null) {
            // 前端或者后端错误！！！
            writer.println(gson.toJson(Result.error("服务器异常！")));
            return;
        }
        response.getWriter().println(gson.toJson(Result.ok(adminVO)));
    }


    private void opAddAdmins(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        // 解析request json 为 AddAdminBo 对象
        String jsonContent = JSONUtil.parseContent(request);

        // jsonContent 转化为bo对象
        // 如果浏览器传来空字符串
        if (StringUtil.isEmpty(jsonContent)) {
            writer.println(gson.toJson(Result.error("前端参数异常！")));
            return;
        }
        // 解析为bo对象
        JsonObject asJsonObject = new JsonParser().parse(jsonContent).getAsJsonObject();
        AddAdminBO adminBO = gson.fromJson(asJsonObject, AddAdminBO.class);
        // 得到code
        int code = adminService.addAdmins(adminBO);
        if (code == 1) {
            // username重复
            writer.println(gson.toJson(Result.error("用户名或昵称重复！")));
            return;
        } else if (code == 0) {
            // 正确返回
            writer.println(gson.toJson(Result.ok()));
            return;
        }
        writer.println(gson.toJson(Result.error("服务器异常！")));
    }

    private void opLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 经常会用到的
        PrintWriter writer = response.getWriter();
        // 获取post请求中的参数 email password（json转化为bo对象）
        String jsonContent = JSONUtil.parseContent(request);

        // jsonContent 转化为bo对象
        // 如果浏览器传来空字符串
        if (StringUtil.isEmpty(jsonContent)) {
            writer.println(gson.toJson(Result.error("前端参数错误！")));
            return;
        }
        // 解析为bo对象
        JsonObject asJsonObject = new JsonParser().parse(jsonContent).getAsJsonObject();
        AdminLoginInfoBO adminBO = gson.fromJson(asJsonObject, AdminLoginInfoBO.class);
        // 通过数据库查询bo，获取 vo
        AdminLoginInfoVO adminVO = adminService.login(adminBO);

        // 判断login状态
        if (adminVO == null) {
            writer.println(gson.toJson(Result.error("用户名或密码错误！")));
            return;
        }
        //登录成功后将 adminId 写入 session 中
        request.getSession().setAttribute("adminId",adminVO.getAdminId());
        writer.println(gson.toJson(Result.ok(adminVO)));


        // 封装为bo对象，传给service，返回code，code+bo封装为响应报文
        // service通过bo对象，通过dao进行sql查询确认
    }

    private void opAllAdmins(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        // 获取 all adminvo list
        List<AllAdminInfoVO> adminVOs = adminService.allAdmins();
        if (adminVOs == null) {
            writer.println(gson.toJson(new Result(404, "列表为空！", null)));
            return;
        }
        // 转换为json对象返回
        response.getWriter().println(gson.toJson(new Result(0, null, adminVOs)));
    }
}
